package com.zackeus.mvvm.api;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleOwner;

import com.trello.lifecycle4.android.lifecycle.AndroidLifecycle;
import com.trello.rxlifecycle4.LifecycleProvider;
import com.zackeus.mvvm.api.response.Response;
import com.zackeus.mvvm.api.response.ResponseObserver;
import com.zackeus.mvvm.base.BaseViewModel;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.observers.DisposableObserver;
import io.reactivex.rxjava3.schedulers.Schedulers;

/**
 * @name: RxRequests
 * @author: zz
 * @date: 2022/9/1
 */
public class RxRequests {

    private RxRequests() {
        throw new UnsupportedOperationException("u can't instantiate me...");
    }

    public static <T extends Response> void request(@NonNull BaseViewModel<?> viewModel,
                                                    @NonNull Observable<T> observable,
                                                    @NonNull ResponseObserver<T> responseObserver) {
        request(viewModel.getLifecycleProvider(), observable, responseObserver);
    }

    public static <T extends Response> void request(@NonNull LifecycleOwner owner,
                                                    @NonNull Observable<T> observable,
                                                    @NonNull ResponseObserver<T> responseObserver) {
        request(AndroidLifecycle.createLifecycleProvider(owner), observable, responseObserver);
    }

    /**
     * subscribeOn() 改变调用它之前代码的线程
     * observeOn() 改变调用它之后代码的线程
     * @param lifecycle
     * @param observable
     * @param responseObserver
     * @param <T>
     */
    public static <T extends Response> void request(@NonNull LifecycleProvider<Lifecycle.Event> lifecycle,
                                                    @NonNull Observable<T> observable,
                                                    @NonNull ResponseObserver<T> responseObserver) {
        observable
                /* 生命周期绑定 */
                .compose(lifecycle.bindToLifecycle())
                /* 指定 IO 线程请求 */
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(disposable -> responseObserver.onBeforeStart())
                /* 控制 doOnSubscribe */
                .subscribeOn(AndroidSchedulers.mainThread())
                .doFinally(responseObserver::onFinally)
                .subscribe(new DisposableObserver<>() {
                    @Override
                    protected void onStart() {
                        /* 此方法不能更改线程 跟发起线程一致 */
                        super.onStart();
                        responseObserver.onStart();
                    }

                    @Override
                    public void onNext(@NonNull T t) {
                        responseObserver.onNext(t);
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        responseObserver.onError(e);
                    }

                    @Override
                    public void onComplete() {
                        responseObserver.onComplete();
                    }
                });
    }
}
